package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.util.CollectionUtils;
import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.entity.UserInfo;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.threadLocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.UUIDUtils;
import com.nineclock.message.dto.SysAllowedJoinCompanyUserDTO;
import com.nineclock.message.enums.MessageTypeEnum;
import com.nineclock.message.pojo.NcMessage;
import com.nineclock.system.config.HxImManager;
import com.nineclock.system.dto.*;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SMSService;
import com.nineclock.system.service.SysCompanyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.security.auth.callback.LanguageCallback;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class SysCompanyServiceImpl implements SysCompanyService {
    //查询当前企业信息
    @Autowired
    private SysCompanyMapper sysCompanyMapper;
    @Autowired
    private OSS oss;


    @Autowired
    private OssProperties ossProperties;

    @Override
    public SysCompanyDTO querySysCompanyInfo() {
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompany sysCompany = sysCompanyMapper.selectById(companyId);

        //健壮性判断防止控制针异常
        if (sysCompany == null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        SysCompanyDTO sysCompanyDTO = BeanHelper.copyProperties(sysCompany, SysCompanyDTO.class);

        return sysCompanyDTO;
    }

    /*
     * 上传企业LOgo
     * */
    @Override
    public String uploadCompanyLogo(MultipartFile file) throws IOException {
        //健壮性判断
        if (file == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //判断文件类型是大小是否符合规则
        if (file.getSize() > NcConstant.maxFileSize) {
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }
        String type = file.getContentType();
        //判断文件类型文件夹类型
        if (!NcConstant.ALLOWED_IMG_TYPES.contains(type)) {
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        //生成一个唯一的文件名称
        String uuid = UUIDUtils.getUUID();
        //获取文件名
        String originalFilename = file.getOriginalFilename();
        //截取后缀
        String extendName = originalFilename.substring(originalFilename.lastIndexOf("."));
        //文件名称那个
        String key = uuid + extendName;
        //上传到数据库的地址名称
        oss.putObject(ossProperties.getBucketName(), key, file.getInputStream());

        //因为上传的要是一个url地址所以要先获取一下文件地址
        String logoUrl = String.format(ossProperties.getHost(), ossProperties.getBucketName()) + key;
        return logoUrl;

    }

    /*
     * 更新企业基本信息
     * */
    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {
        //健壮性判断
        if (sysCompanyDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        // 获取企业id
        UserInfo userInfo = CurrentUserHolder.get();
        Long companyId = userInfo.getCompanyId();
        //获取数据库数据
        SysCompany sysCompany = sysCompanyMapper.selectById(companyId);

        //健壮性查看企业信息是否为空
        if (sysCompany == null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        sysCompany.setLogo(sysCompanyDTO.getLogo());
        sysCompany.setName(sysCompanyDTO.getName());
        //将修改的数据保存到数据库
        sysCompanyMapper.updateById(sysCompany);
    }

    @Autowired
    private SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysCompanyUserMapper companyUserMapper;

    @Autowired
    private SMSService smsService;

    //更新权限列表
    @Override
    public void updateChangeMainManagerAdmin(SysChangeMainManagerDTO sysChangeMainManagerDTO) {
        //健壮性判断是否为空
        if (sysChangeMainManagerDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //获取新的更改后用户的id
        Long userId = sysChangeMainManagerDTO.getUserId();

        SysCompanyUser companyUser = companyUserMapper.selectById(userId);
        Boolean verifyCode = smsService.verifyCode(sysChangeMainManagerDTO.getCode(), companyUser.getMobile(), SMSConstant.SMS_TYPE_CHANGE_MANAGER);
        if (!verifyCode) {
            throw new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }

        //获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //获取权限id
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleName, "ROLE_ADMIN_SYS");
        wrapper.eq(SysRole::getCompanyId, companyId);
        SysRole sysRole = sysRoleMapper.selectOne(wrapper);
        //健壮性判断
        if (sysRole == null) {
            throw new NcException(ResponseEnum.ROLE_NOT_FOUND);
        }
        //系统主管理员id
        Long roleId = sysRole.getId();

        LambdaQueryWrapper<SysCompanyUserRole> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysCompanyUserRole::getCompanyId, companyId);
        userWrapper.eq(SysCompanyUserRole::getRoleId, roleId);

        //获取拥有相同权限,公司的
        SysCompanyUserRole sysCompanyUserRole = companyUserRoleMapper.selectOne(userWrapper);
        //设置id
        if (sysCompanyUserRole == null) {
            throw new NcException(ResponseEnum.ERROR);
        }
        sysCompanyUserRole.setCompanyUserId(userId);
        //修改
        companyUserRoleMapper.update(sysCompanyUserRole, userWrapper);
    }

    /*根据关键字查询企业*/
    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {

        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(SysCompany::getName, keyword);

        List<SysCompany> sysCompanies = sysCompanyMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(sysCompanies)) {
            return BeanHelper.copyWithCollection(sysCompanies, SysCompanyDTO.class);
        }

        return null;
    }
    /*
     * 申请加入企业
     * */

    @Autowired
    SysUserMapper userMapper;

    @Autowired
    RocketMQTemplate rocketMQTemplate;

    @Autowired
    private HxImManager hxImManager;
    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO sysApplyJoinCompanyUserDTO) {

        //健壮性判断是否为空
        if (sysApplyJoinCompanyUserDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //根据用户id获取数据然后储存
        SysUser user = userMapper.selectById(sysApplyJoinCompanyUserDTO.getUserId());
        user.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        user.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        user.setUpdateTime(new Date());
        user.setLastLoginCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        //将已修改的数据更新到数据库
        userMapper.updateById(user);

        //创建员工表
        SysCompanyUser companyUser = new SysCompanyUser();
        companyUser.setUserId(sysApplyJoinCompanyUserDTO.getUserId());//用户id
        companyUser.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());//企业id
        companyUser.setCompanyName(sysApplyJoinCompanyUserDTO.getCompanyName());//企业名称
        companyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason());//申请理由
        companyUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());//email
        companyUser.setCreateTime(new Date());//创建时间
        companyUser.setTimeEntry(new Date());//入职时间
        companyUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile()); //手机号
        companyUser.setUserName(sysApplyJoinCompanyUserDTO.getUserName());//用户名
        companyUser.setImageUrl(sysApplyJoinCompanyUserDTO.getImageUrl());//图片地址
        companyUser.setEnable((short) 1);
        companyUser.setPost(sysApplyJoinCompanyUserDTO.getPost()); //职位
        companyUserMapper.insert(companyUser);

        //要发送的具具体信息
        SysCompanyUser currentAdmin = companyUserMapper.getCurrentAdmin(sysApplyJoinCompanyUserDTO.getCompanyId());
        NcMessage message = new NcMessage();

        message.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType()); //消息类型
        message.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience()); //消息别名推送
        message.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle());//消息表弟
        message.setCreateTime(new Date()); //创建时间
        message.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId() + ""); //企业id
        message.setContent(sysApplyJoinCompanyUserDTO.getUserName() + "正在申请加入企业,请及时查看");//消息摘要
        message.setUseStatus(0);//是否使用状态
        message.setTargets(Arrays.asList(currentAdmin.getMobile())); //申请人手机号作目标人标识
        message.setApproveStatue(0);//申请状态 0未审核
        message.setApplyUserId(sysApplyJoinCompanyUserDTO.getUserId()); //申请人id
        message.setApplyUsername(sysApplyJoinCompanyUserDTO.getUserName()); //申请人用户名
        message.setApproveUserId(currentAdmin.getUserId());// 审批人用户id
        message.setApproveUsername(currentAdmin.getUserName()); //审批人用户名称

        //申请加入企业后发送信息到mq.推送消息通知管理员

        rocketMQTemplate.convertAndSend("messagePushTopic", message);

        //把用户信息注册到环信
        SysUser user1 = new SysUser();
        user1.setUsername(sysApplyJoinCompanyUserDTO.getCompanyName());
        user1.setPassword("123456");
        hxImManager.registerUser2HuanXing(user1);
    }

    //企业审核
    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO allowedJoinCompanyUserDTO) {

        //根据企业id 和申请人id获取员工信息
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysCompanyUser::getUserId,allowedJoinCompanyUserDTO.getApplyUserId());

        SysCompanyUser companyUser = companyUserMapper.selectOne(wrapper);

        //修改审核状态
        if (companyUser==null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //发送Mq请求,推送给该用户,通知审核通过
        NcMessage message = new NcMessage();

        message.setMessageType(MessageTypeEnum.COMPANY_APPROVE.getType()); //消息类型
        message.setAudience(MessageTypeEnum.COMPANY_APPROVE.getAudience()); //消息别名推送
        message.setTitle(MessageTypeEnum.COMPANY_APPROVE.getTitle());//消息表弟
        message.setCreateTime(new Date()); //创建时间
        message.setCompanyId(companyUser.getCompanyId() + ""); //企业id
        if (allowedJoinCompanyUserDTO.getApproved()){
            message.setContent("恭喜您,通过了审核");
        }else {
            message.setContent("很遗憾,您没有通过审核");
        }

        message.setUseStatus(1);//是否使用状态
        message.setTargets(Arrays.asList(companyUser.getMobile())); //申请人手机号作目标人标识
        message.setApproveStatue(1);//申请状态 0未审核
        message.setApplyUserId(companyUser.getUserId()); //申请人id
        message.setApplyUsername(companyUser.getUserName()); //申请人用户名
        message.setApproveUserId(CurrentUserHolder.get().getId());// 审批人用户id
        message.setApproveUsername(CurrentUserHolder.get().getUsername()); //审批人用户名称

        //申请加入企业后发送信息到mq.推送消息通知管理员

        rocketMQTemplate.convertAndSend("messagePushTopic", message);

    }
}
